/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package com.unwiredgrain.modeling.sscm.impl;

import com.unwiredgrain.modeling.sscm.IntTemplateInstantiation;
import com.unwiredgrain.modeling.sscm.IntTemplateArgument;
import com.unwiredgrain.modeling.sscm.IntTemplateParameter;
import com.unwiredgrain.modeling.sscm.IntegerValue;
import com.unwiredgrain.modeling.sscm.SSCMPackage;
import com.unwiredgrain.modeling.sscm.TemplateInstantiation;
import com.unwiredgrain.modeling.sscm.TemplateArgument;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EcoreEList;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Int Template Argument</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link com.unwiredgrain.modeling.sscm.impl.IntTemplateInstantiationImpl#getIntegerValue <em>Integer Value</em>}</li>
 *   <li>{@link com.unwiredgrain.modeling.sscm.impl.IntTemplateInstantiationImpl#getIntArgument <em>Int Argument</em>}</li>
 *   <li>{@link com.unwiredgrain.modeling.sscm.impl.IntTemplateInstantiationImpl#getValue <em>Value</em>}</li>
 *   <li>{@link com.unwiredgrain.modeling.sscm.impl.IntTemplateInstantiationImpl#getIntTemplateParameter <em>Int Template Parameter</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class IntTemplateInstantiationImpl extends NonTypeTemplateInstantiationImpl implements IntTemplateInstantiation {
	/**
	 * The cached value of the '{@link #getIntegerValue() <em>Integer Value</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIntegerValue()
	 * @generated
	 * @ordered
	 */
	protected IntegerValue integerValue;

	/**
	 * The cached value of the '{@link #getIntArgument() <em>Int Argument</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIntArgument()
	 * @generated
	 * @ordered
	 */
	protected IntTemplateArgument intArgument;

	/**
	 * The default value of the '{@link #getValue() <em>Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getValue()
	 * @generated
	 * @ordered
	 */
	protected static final Integer VALUE_EDEFAULT = null;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IntTemplateInstantiationImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return SSCMPackage.Literals.INT_TEMPLATE_INSTANTIATION;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntegerValue getIntegerValue() {
		return integerValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetIntegerValue(IntegerValue newIntegerValue, NotificationChain msgs) {
		IntegerValue oldIntegerValue = integerValue;
		integerValue = newIntegerValue;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE, oldIntegerValue, newIntegerValue);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIntegerValue(IntegerValue newIntegerValue) {
		if (newIntegerValue != integerValue) {
			NotificationChain msgs = null;
			if (integerValue != null)
				msgs = ((InternalEObject)integerValue).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE, null, msgs);
			if (newIntegerValue != null)
				msgs = ((InternalEObject)newIntegerValue).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE, null, msgs);
			msgs = basicSetIntegerValue(newIntegerValue, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE, newIntegerValue, newIntegerValue));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntTemplateArgument getIntArgument() {
		if (intArgument != null && intArgument.eIsProxy()) {
			InternalEObject oldIntArgument = (InternalEObject)intArgument;
			intArgument = (IntTemplateArgument)eResolveProxy(oldIntArgument);
			if (intArgument != oldIntArgument) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_ARGUMENT, oldIntArgument, intArgument));
			}
		}
		return intArgument;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntTemplateArgument basicGetIntArgument() {
		return intArgument;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIntArgument(IntTemplateArgument newIntArgument) {
		IntTemplateArgument oldIntArgument = intArgument;
		intArgument = newIntArgument;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_ARGUMENT, oldIntArgument, intArgument));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public Integer getValue() {
		// DONE: implement this method to return the 'Value' attribute
		// Ensure that you remove @generated or mark it @generated NOT
		// throw new UnsupportedOperationException();
		IntTemplateArgument ita = getIntArgument();
		if (ita == null || !(ita instanceof IntegerValue)) {
			// assertion
			if (getIntegerValue() != null) {
				throw new UnsupportedOperationException();
			}
			
			return null;
		}
		
		// now it's assured integerValue is set as intArgument
		return new Integer(getIntegerValue().getValue());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public void setValue(Integer newValue) {
		// DONE: implement this method to set the 'Value' attribute
		// Ensure that you remove @generated or mark it @generated NOT
		// throw new UnsupportedOperationException();
		
		// if integerValue does not exist, create it.
		if (getIntegerValue() == null) {
			IntegerValue iv = SSCMFactoryImpl.eINSTANCE.createIntegerValue();
			setIntegerValue(iv);
		}
		
		// set the value
		getIntegerValue().setValue(newValue);
		
		// set intArgument, this automatically remove intTemplateParameter if any.
		setIntArgument(getIntegerValue());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntTemplateParameter getIntTemplateParameter() {
		IntTemplateParameter intTemplateParameter = basicGetIntTemplateParameter();
		return intTemplateParameter != null && intTemplateParameter.eIsProxy() ? (IntTemplateParameter)eResolveProxy((InternalEObject)intTemplateParameter) : intTemplateParameter;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public IntTemplateParameter basicGetIntTemplateParameter() {
		// DONE: implement this method to return the 'Int Template Parameter' reference
		// -> do not perform proxy resolution
		// Ensure that you remove @generated or mark it @generated NOT
		// throw new UnsupportedOperationException();
		IntTemplateArgument ita = getIntArgument();
		if (ita == null || !(ita instanceof IntTemplateParameter)) {
			return null;
		}
		
		return (IntTemplateParameter)ita;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public void setIntTemplateParameter(IntTemplateParameter newIntTemplateParameter) {
		// DONE: implement this method to set the 'Int Template Parameter' reference
		// Ensure that you remove @generated or mark it @generated NOT
		// throw new UnsupportedOperationException();
		setIntegerValue(null);
		setIntArgument(newIntTemplateParameter);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE:
				return basicSetIntegerValue(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE:
				return getIntegerValue();
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_ARGUMENT:
				if (resolve) return getIntArgument();
				return basicGetIntArgument();
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__VALUE:
				return getValue();
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_TEMPLATE_PARAMETER:
				if (resolve) return getIntTemplateParameter();
				return basicGetIntTemplateParameter();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE:
				setIntegerValue((IntegerValue)newValue);
				return;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_ARGUMENT:
				setIntArgument((IntTemplateArgument)newValue);
				return;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__VALUE:
				setValue((Integer)newValue);
				return;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_TEMPLATE_PARAMETER:
				setIntTemplateParameter((IntTemplateParameter)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE:
				setIntegerValue((IntegerValue)null);
				return;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_ARGUMENT:
				setIntArgument((IntTemplateArgument)null);
				return;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__VALUE:
				setValue(VALUE_EDEFAULT);
				return;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_TEMPLATE_PARAMETER:
				setIntTemplateParameter((IntTemplateParameter)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INTEGER_VALUE:
				return integerValue != null;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_ARGUMENT:
				return intArgument != null;
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__VALUE:
				return VALUE_EDEFAULT == null ? getValue() != null : !VALUE_EDEFAULT.equals(getValue());
			case SSCMPackage.INT_TEMPLATE_INSTANTIATION__INT_TEMPLATE_PARAMETER:
				return basicGetIntTemplateParameter() != null;
		}
		return super.eIsSet(featureID);
	}
	
	/**
	 * 
	 */
	@Override
	public TemplateArgument basicGetArgument() {
		return intArgument;
	}
	
	/**
	 * 
	 */
	@Override
	public EList<? extends TemplateInstantiation> getSubArguments() {
		return new EcoreEList.UnmodifiableEList<TemplateInstantiation>(this, null, 0, null);
	}
	
	/**
	 * 
	 */
	@Override
	public String getCppName() {
		if (getIntArgument() == null) {
			return null;
		}
		
		if (getIntArgument() instanceof IntTemplateParameter) {
			return ((IntTemplateParameter)getIntArgument()).getName();
		}
		
		if (getIntArgument() instanceof IntegerValue) {
			IntegerValue iv = (IntegerValue)getIntArgument();
			return Integer.toString(iv.getValue());
		}
		
		return "[ERROR]";
	}
} //IntTemplateArgumentImpl
